Fix GIC_IPRIORITYR setting in new drivers
authorSoby Mathew <[email protected]>
Fri, 15 Jan 2016 14:20:57 +0000 (14:20 +0000)
committerSoby Mathew <[email protected]>
Tue, 9 Feb 2016 16:50:36 +0000 (16:50 +0000)
The code to set the interrupt priority for secure interrupts in the
new GICv2 and GICv3 drivers is incorrect. The setup code to configure
interrupt priorities of secure interrupts, one interrupt at a time, used
gicd_write_ipriorityr()/gicr_write_ipriority() function affecting
4 interrupts at a time. This bug did not manifest itself because all the
secure interrupts were configured to the highest secure priority(0) during
cold boot and the adjacent non secure interrupt priority would be configured
later by the normal world. This patch introduces new accessors,
gicd_set_ipriorityr() and gicr_set_ipriorityr(), for configuring priority
one interrupt at a time and fixes the the setup code to use the new
accessors.

Fixes ARM-software/tf-issues#344

Change-Id: I470fd74d2b7fce7058b55d83f604be05a27e1341

drivers/arm/gic/common/gic_common.c
drivers/arm/gic/v2/gicv2_helpers.c
drivers/arm/gic/v3/gicv3_helpers.c
include/drivers/arm/gic_common.h

index 17be61d5ec545b71f2838185530802c98f20f60c..2c901bc29cd727a9826035ba298f51c5d3be8ef8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -306,3 +306,8 @@ void gicd_set_icactiver(uintptr_t base, unsigned int id)
 
        gicd_write_icactiver(base, id, (1 << bit_num));
 }
+
+void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
+{
+       mmio_write_8(base + GICD_IPRIORITYR + id, pri & GIC_PRI_MASK);
+}
index 8c4e2f0f114fd72a8dc77d47f0d835c13b5a275e..e9ae7dfab99d3e848e8579702281eacb5d00bd2f 100644 (file)
@@ -163,7 +163,7 @@ void gicv2_secure_spis_configure(uintptr_t gicd_base,
                        gicd_clr_igroupr(gicd_base, irq_num);
 
                        /* Set the priority of this interrupt */
-                       gicd_write_ipriorityr(gicd_base,
+                       gicd_set_ipriorityr(gicd_base,
                                              irq_num,
                                              GIC_HIGHEST_SEC_PRIORITY);
 
@@ -210,7 +210,7 @@ void gicv2_secure_ppi_sgi_setup(uintptr_t gicd_base,
                        sec_ppi_sgi_mask |= 1U << irq_num;
 
                        /* Set the priority of this interrupt */
-                       gicd_write_ipriorityr(gicd_base,
+                       gicd_set_ipriorityr(gicd_base,
                                            irq_num,
                                            GIC_HIGHEST_SEC_PRIORITY);
                }
index 2fb98cbbd86627ac81134c16efe4af749dacec2a..4a565045f1b9273bcb8b4d7f95a193d9ed8a864d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -194,6 +194,15 @@ void gicr_set_isenabler0(uintptr_t base, unsigned int id)
        gicr_write_isenabler0(base, (1 << bit_num));
 }
 
+/*
+ * Accessor to set the byte corresponding to interrupt ID
+ * in GIC Re-distributor IPRIORITYR.
+ */
+void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
+{
+       mmio_write_8(base + GICR_IPRIORITYR + id, pri & GIC_PRI_MASK);
+}
+
 /******************************************************************************
  * This function marks the core as awake in the re-distributor and
  * ensures that the interface is active.
@@ -330,7 +339,7 @@ void gicv3_secure_spis_configure(uintptr_t gicd_base,
                                gicd_clr_igrpmodr(gicd_base, irq_num);
 
                        /* Set the priority of this interrupt */
-                       gicd_write_ipriorityr(gicd_base,
+                       gicd_set_ipriorityr(gicd_base,
                                              irq_num,
                                              GIC_HIGHEST_SEC_PRIORITY);
 
@@ -404,7 +413,7 @@ void gicv3_secure_ppi_sgi_configure(uintptr_t gicr_base,
                                gicr_clr_igrpmodr0(gicr_base, irq_num);
 
                        /* Set the priority of this interrupt */
-                       gicr_write_ipriorityr(gicr_base,
+                       gicr_set_ipriorityr(gicr_base,
                                            irq_num,
                                            GIC_HIGHEST_SEC_PRIORITY);
 
index 6a322a22a078df45b3835aeffe8a60797391a4ff..47d06696592912cba2dccbd46562b2dd11d5c0f5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -167,6 +167,7 @@ void gicd_set_ispendr(uintptr_t base, unsigned int id);
 void gicd_set_icpendr(uintptr_t base, unsigned int id);
 void gicd_set_isactiver(uintptr_t base, unsigned int id);
 void gicd_set_icactiver(uintptr_t base, unsigned int id);
+void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri);
 
 
 #endif /* __ASSEMBLY__ */